"""
@-*- coding: utf-8 -*-
@ python：python 3.8
@ 创建人员:ylx-lingxiao
@ 创建时间:2025/5/13  23:05
@ Explanation:读取数据层的yaml文件中的变量引用，借用反射机制，触发对应的方法执行，得到结果后回填至yaml文件

这个模块使用上个人认为，是在逻辑层，读取yaml文件时，使用这个方法来针对性的读取，以前可能直接通过read_yaml
读取获取整个yaml的数据，现在针对有变量占位的yaml文件，中间需要处理一下，然后再把加工过的数据给逻辑层使用即可

本模块实现了：对数据层-yaml文件的加工，并返回加工后的yaml数据文件，目的是完成对yaml文件中变量的替换
"""
import json
import re
from common.get_value_to_yaml import YamlHotLoad
from common.yaml_hander import read_yaml


class RequestBase:
    @classmethod
    def parse_and_replace_variables(cls, yaml_data):
        """
        解析并替换yaml数据中的变量引用，如${get_token()}
        :param yaml_data:需要解析的yaml数据，可以理解为通过read_yaml方法读取整个yaml文件得到的返回值
        :return:
        """
        # 处理yaml_data数据为字符串类型，read_yaml读取到的yaml数据均为列表或字典类型
        # ensure_ascii 设置为False 允许输出中文
        yaml_data_str = yaml_data if isinstance(yaml_data, str) else json.dumps(yaml_data, ensure_ascii=False)

        # 寻找引用变量占位符
        for _ in range(yaml_data_str.count("${")):
            if "${" in yaml_data_str and "}" in yaml_data_str:
                # 准备提取第一个变量引用的方法名及参数，先确认开始和结尾的索引，方便后续字符串切片
                start_index = yaml_data_str.index("$")
                end_index = yaml_data_str.index("}", start_index)
                variable_data = yaml_data_str[start_index:end_index + 1]

                # 使用正则表达式提取函数名、参数
                # re.match匹配后，会返回一个匹配对象，其有相关方法支持将函数名、入参分别提取
                match = re.match(r"\$\{(\w+)\((.*?)\)}", variable_data)
                if match:
                    func_name, func_params = match.groups()
                    func_params_list = func_params.split(",") if func_params else []

                    # 反射机制调用函数,调用类中的类方法，可以采用实例化类后调用，getattr(对象，str-方法名)
                    # 去YamlHotLoad类中触发对应的方法，所以就要导入这个类
                    extract_data = getattr(YamlHotLoad(), func_name)(*func_params_list)

                    # 打印替换之前的yaml_data json 字符串
                    # print(yaml_data_str, type(yaml_data_str))

                    # 替换原始字符串中变量引用为调用后的结果
                    # re.sub 方法用于搜索指定模式的子串，并将其替换成另一个字符串
                    # re.escape 用户转义字符串中所有的正则表达式元字符，让其被作为普通字符处理
                    yaml_data_str = re.sub(re.escape(variable_data), str(extract_data), yaml_data_str)

                    # 打印替换之后的yaml_data_str
                    # print(yaml_data_str, type(yaml_data_str))
        try:
            # 将json格式的字符串，反序列化为Python对象
            data = json.loads(yaml_data_str)
        except json.JSONDecodeError:
            data = yaml_data_str

        return data


if __name__ == "__main__":
    path = "../data/armory_main.yaml"
    res_1 = read_yaml(path)
    print(res_1)
    print(type(res_1))
    #
    # res_2 = json.dumps(res_1, ensure_ascii=False)
    # print(res_2)
    # print(type(res_2))
    # print(res_2[0])
    test_1 = RequestBase()
    res_2 = test_1.parse_and_replace_variables(res_1)
    res_2_file_path = test_1.parse_and_replace_variables(res_1)[1]["test_cases"][1]["input"]["command_4"]["update_armory_json_file_path"]
    res_2_document = test_1.parse_and_replace_variables(res_1)[1]["test_cases"][1]["input"]["command_4"]["update_armory_json_document"]
    print(res_2)
    print(type(res_2))
    print(res_2_file_path)
    print(type(res_2_file_path))
    print(res_2_document)
    print(type(res_2_document))
